package com.flmz.system.service.question.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.flmz.common.core.constants.Constants;
import com.flmz.common.core.enums.ResultCode;
import com.flmz.common.security.exception.ServiceException;
import com.flmz.system.domain.question.Question;
import com.flmz.system.domain.question.dto.QuestionAddDTO;
import com.flmz.system.domain.question.dto.QuestionEditDTO;
import com.flmz.system.domain.question.dto.QuestionQueryDTO;
import com.flmz.system.domain.question.es.QuestionES;
import com.flmz.system.domain.question.vo.QuestionDetailVO;
import com.flmz.system.domain.question.vo.QuestionVO;
import com.flmz.system.elasticsearch.QuestionRepository;
import com.flmz.system.manager.QuestionCacheManager;
import com.flmz.system.mapper.question.QuestionMapper;
import com.flmz.system.service.question.IQuestionService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class QuestionServiceImpl implements IQuestionService {

	@Autowired
	private QuestionMapper questionMapper;

	@Autowired
	private QuestionRepository questionRepository;

	@Autowired
	private QuestionCacheManager questionCacheManager;

	@Override
	public List<QuestionVO> list(QuestionQueryDTO questionQueryDTO) {
		// 排除已经添加过的题目（竞赛列表处）
		String excludeIdStr = questionQueryDTO.getExcludeIdStr();
		if (StrUtil.isNotEmpty(excludeIdStr)) {
			String[] excludeIdArr = excludeIdStr.split(Constants.SPLIT_SEM);
			Set<Long> excludeIdSet = Arrays.stream(excludeIdArr)
					.map(Long::valueOf)
					.collect(Collectors.toSet());
			questionQueryDTO.setExcludeIdSet(excludeIdSet);
		}

		PageHelper.startPage(questionQueryDTO.getPageNum(), questionQueryDTO.getPageSize());
		List<QuestionVO> questionVOList = questionMapper.selectQuestionList(questionQueryDTO);
		return questionVOList;
	}

	public boolean add(QuestionAddDTO questionAddDTO) {
		// 校验新增题目标题与数据库中现有的题目是否一致
		List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<Question>()
				.eq(Question::getTitle, questionAddDTO.getTitle()));
		if (CollectionUtil.isNotEmpty(questionList)) {
			throw new ServiceException(ResultCode.FAILED_ALREADY_EXISTS);
		}

		Question question = new Question();
		BeanUtil.copyProperties(questionAddDTO, question);

		// 先插入数据库，再加入es
		int insert = questionMapper.insert(question);
		if (insert <= 0) {
			return false;
		}
		QuestionES questionES = new QuestionES();
		BeanUtil.copyProperties(question, questionES);
		questionRepository.save(questionES);
		questionCacheManager.addCache(question.getQuestionId()); // 维护redis
		return true;
	}

	@Override
	public QuestionDetailVO detail(Long questionId) {
		// 判断要查询的题目是否存在
		Question question = questionMapper.selectById(questionId);
		if (question == null) {
			throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
		}

		QuestionDetailVO questionDetailVO = new QuestionDetailVO();
		BeanUtil.copyProperties(question, questionDetailVO);
		return questionDetailVO;
	}

	@Override
	public int edit(QuestionEditDTO questionEditDTO) {
		// 判断要编辑的题目是否存在
		Question oldQuestion = questionMapper.selectById(questionEditDTO.getQuestionId());
		if (oldQuestion == null) {
			throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
		}

		oldQuestion.setTitle(questionEditDTO.getTitle());
		oldQuestion.setDifficulty(questionEditDTO.getDifficulty());
		oldQuestion.setTimeLimit(questionEditDTO.getTimeLimit());
		oldQuestion.setSpaceLimit(questionEditDTO.getSpaceLimit());
		oldQuestion.setContent(questionEditDTO.getContent());
		oldQuestion.setQuestionCase(questionEditDTO.getQuestionCase());
		oldQuestion.setDefaultCode(questionEditDTO.getDefaultCode());
		oldQuestion.setMainFuc(questionEditDTO.getMainFuc());

		// 编辑完需要同步更新es
		QuestionES questionES = new QuestionES();
		BeanUtil.copyProperties(oldQuestion, questionES);
		questionRepository.save(questionES);
		return questionMapper.updateById(oldQuestion);
	}

	@Override
	public int delete(Long questionId) {
		Question question = questionMapper.selectById(questionId);
		if (question == null) {
			throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
		}

		// 删除es中的题目
		questionRepository.deleteById(questionId);
		questionCacheManager.deleteCache(questionId); // 维护redis
		return questionMapper.deleteById(questionId);
	}
}
